package com.topscomm.meet;

import com.topscomm.base.BaseSystemConst;
import com.topscomm.base.pojo.BaseRemindTaskEntity;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.cbo.pojo.CboAttachmentEntity;
import com.topscomm.cbo.pojo.CboAttachmentTypeEntity;
import com.topscomm.cbo.service.ICboAttachmentService;
import com.topscomm.cbo.service.ICboAttachmentTypeService;
import com.topscomm.meet.utils.GenerateExcelTemplateUtil;
import com.topscomm.meet.utils.GeneratePPTTemplateUtil;
import com.topscomm.meet.utils.GenerateWordTemplateUtil;
import com.topscomm.mis.MisService;
import com.topscomm.pub.util.*;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.TapService;
import com.topscomm.tap.common.ParameterCache;
import com.topscomm.tap.common.SessionUserBean;
import com.topscomm.tap.common.TapSystemConst;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.io.ZipInputStream;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.unzip.UnzipUtil;
import org.springframework.beans.factory.annotation.Autowired;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
import java.util.function.UnaryOperator;


@SuppressWarnings("rawtypes")
public class MeetService<T extends MeetEntity, TDao extends IMeetDao> extends MisService<T, TDao>
		implements IMeetService<T, TDao> {
	@Autowired
	private  ICboAttachmentService  cboAttachmentService;
	@Autowired
	private ICboAttachmentTypeService cboAttachmentTypeService;

	/**
	 * 统一的给扩充字段赋值，第一个为单号，第二个为申请部门，第三个位申请人
	 */
	@Override
	protected void afterSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
		try {
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendLineSingle("update CboApprovalFlowIns set ");
			sql.appendLineSingle("extendfield1 = (select docno from {0} "
					+ "where CboApprovalFlowIns.sourceid = {0}.id " + "and CboApprovalFlowIns.sourcetype = '{0}'),",
					entity.getTableName());
			sql.appendLineSingle("extendfield2 = (select deptcode from {0} "
					+ "where CboApprovalFlowIns.sourceid = {0}.id " + "and CboApprovalFlowIns.sourcetype = '{0}'),",
					entity.getTableName());
			sql.appendLineSingle("extendfield3 = (select usercode from {0} "
					+ "where CboApprovalFlowIns.sourceid = {0}.id " + "and CboApprovalFlowIns.sourcetype = '{0}')",
					entity.getTableName());
			sql.appendLineSingle("where sourceid = '{0}' and sourcetype='{1}'", entity.getId(), entity.getTableName());
			this.getDao().updateExecute(sql.toString());
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		super.afterSubmit(entity, sessionUserBean);
	}

	/**
	 * @Description: 转pdf后下载模板文件
	 * @Author: mengmeng
	 * @Date: 2021/8/16 14:14
	 * @Version: 1.0
	 */
	@Override
	public Map<String, Object> executeDownload(Map<String, Object> paraMap) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			// 附件对象
			StringBufferProxy sqlWhere = new StringBufferProxy();
			if (paraMap.containsKey("attachmentId")) {
				String attachmentId = ConvertUtil.convertToString(paraMap.get("attachmentId"));
				sqlWhere.appendLineSingle(" id={0}", attachmentId);
			} else {
				sqlWhere.appendLineSingle(" 1=1 ");
				if (paraMap.containsKey("sourcetype")) {
					sqlWhere.appendLineSingle(" and sourcetype='{0}'",
							ConvertUtil.convertToString(paraMap.get("sourcetype")));
				}
				if (paraMap.containsKey("sourceid")) {
					sqlWhere.appendLineSingle(" and sourceid='{0}'",
							ConvertUtil.convertToString(paraMap.get("sourceid")));
				}
			}
			Map<String, Object> queryMap = new HashMap<String, Object>();
			queryMap.put("whereSql", sqlWhere.toString());
			CboAttachmentEntity attachment = cboAttachmentService.getByte(queryMap);
			resultMap.put("attFileName", attachment.getDisplayname());
			// 存储配置
			CboAttachmentTypeEntity attachmentType = cboAttachmentTypeService
					.queryById(ConvertUtil.convertToString(attachment.getAttachmenttypeid()));
			if (attachmentType == null) {
				throw new ServiceException("没有设置正确的配置参数！");
			}
			if (attachmentType.getStoretype().equals(TapSystemConst.TapAttachmentStoreType.FTP)) {
				downloadFtp(resultMap, paraMap, attachment, attachmentType);
			}
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		return resultMap;
	}

	/**
	 * @Description:    下载文件后转ftp
	 * @Author:         mengmeng
	 * @Date:           2021/8/19 9:57
	 * @Version:        1.0
	 */
	private void downloadFtp(Map<String, Object> resultMap, Map<String, Object> paraMap, CboAttachmentEntity attachment,
							 CboAttachmentTypeEntity attachmentType) {
		try {
			FTPProcessor ftpProcessor = null;
			ZipInputStream is = null;
			OutputStream os = null;
			String tempZipFilePath = null;
			String unZipFilePath = null;
			String tempZipDirectoryName = null;
			String uuid = UUID.randomUUID().toString();
			String property = System.getProperties().getProperty("file.separator");
			try {
				// 临时目录，用于解压缩文件
				tempZipDirectoryName = BaseUtil.getProjectPath() + "zip" + property + uuid;
				File tempZipDirectory = new File(tempZipDirectoryName);
				if (!tempZipDirectory.exists() && !tempZipDirectory.isDirectory()) {
					tempZipDirectory.mkdirs();
				}
				// 打开FTP连接,下载并解压
				ftpProcessor = new FTPProcessor();
				ftpProcessor.connect(attachmentType.getFtppath(), attachmentType.getFtpserver(),
						Integer.parseInt(attachmentType.getFtpport()), attachmentType.getFtpuser(),
						attachmentType.getFtppwd());
				// Ftp文件路径
				String ftpFilePath = attachment.getSavepath() + attachment.getFilename();
				// Zip文件下载路径，下载Zip文件
				tempZipFilePath = tempZipDirectoryName + property + attachment.getFilename();
				ftpProcessor.download(ftpFilePath, tempZipFilePath);
				String displayName = attachment.getDisplayname();
				if (attachmentType.getCompresszip() == 0)// 不压缩
				{
					resultMap.put("attFileName", displayName);
					resultMap.put("attInputStream", FileUtil.convertFileToBytes(tempZipFilePath));
				} else {
					// 解压
					ZipFile zipFile = new ZipFile(tempZipFilePath);
					zipFile.setFileNameCharset("GBK");
					if (zipFile.isEncrypted()) {
						zipFile.setPassword(attachment.getPwd());
					}
					List<FileHeader> fileHeaderList = zipFile.getFileHeaders();
					FileHeader fileHeader = fileHeaderList.get(0);
					if (fileHeader != null) {
						unZipFilePath = tempZipDirectoryName + property + displayName;
						File unZipFile = new File(unZipFilePath);
						if (fileHeader.isDirectory()) {
							unZipFile.mkdirs();
						}
						is = zipFile.getInputStream(fileHeader);
						os = new FileOutputStream(unZipFile);
						int readLen = -1;
						byte[] buff = new byte[4096];
						while ((readLen = is.read(buff)) != -1) {
							os.write(buff, 0, readLen);
						}
						UnzipUtil.applyFileAttributes(fileHeader, unZipFile);
						String extentionOfUnzipFile = FileUtil.getExtention(displayName);
						String convertDisplayName = displayName.substring(0, displayName.indexOf(extentionOfUnzipFile)) + ".pdf";
						String destDirectory = tempZipDirectoryName + property + convertDisplayName;
						if (".docx".equals(extentionOfUnzipFile) || ".doc".equals(extentionOfUnzipFile) ) {
							GenerateWordTemplateUtil.convertToPdf(unZipFilePath, destDirectory);
						}
						else if(".xlsx".equals(extentionOfUnzipFile) || ".xls".equals(extentionOfUnzipFile)) {
							GenerateExcelTemplateUtil.convertToPdf(unZipFilePath, destDirectory);
						}
						else if(".pptx".equals(extentionOfUnzipFile) || ".ppt".equals(extentionOfUnzipFile)) {
							GeneratePPTTemplateUtil.convertToPdf(unZipFilePath, destDirectory);
						}
						else if(".pdf".equals(extentionOfUnzipFile)) {
						}
						else if(isImage(unZipFilePath)){
							GenerateWordTemplateUtil.convertImageToPdf(unZipFilePath, destDirectory);
						}
						else {
							throw new ServiceException("暂不支持该格式文件预览！");
						}

						resultMap.put("attFileName", convertDisplayName);
						resultMap.put("attInputStream", FileUtil.convertFileToBytes(destDirectory));
					}
				}
			} catch (Exception ex) {
				throw new ServiceException(ex);
			} finally {
				if (os != null) {
					os.close();
					os = null;
				}
				if (is != null) {
					is.close();
					is = null;
				}
				if (ftpProcessor != null) {
					ftpProcessor.close();
				}
				// 删除压缩文件
				FileUtil.deleteFile(tempZipFilePath);
				if (ParameterCache.getBooleanValue("CboAttchmentUnZipDelete", true)) {
					// 删除解压后的文件
					if (unZipFilePath != null) {
						FileUtil.deleteFile(unZipFilePath);
					}
					// 删除临时目录
					FileUtil.deleteDirectory(tempZipDirectoryName, true);
				} else {
					// edit by jichanghong 20180719
					// 电子工艺文件管理系统，根据工序拆分pdf文件要用unZipFilePath 与
					// tempZipDirectoryName
					resultMap.put("unZipFilePath", unZipFilePath);
					resultMap.put("tempZipDirectoryName", tempZipDirectoryName);
				}
			}
		} catch (Exception ex) {
			throw new ServiceException(ex);
		}
	}

	/**
	 * 用来处理重复拼串
	 * @param
	 * @return
	 * @throws
	 * @author xinfushuo
	 * @date 2022/11/24
	 * @modify
	 */
	@Override
	public  StringBufferProxy appendSql(Map<String, Object> paraMap, StringBufferProxy sql, String paramName, String template, UnaryOperator<String> handleParam) {
		if(paraMap.containsKey(paramName)){
			String value = paraMap.get(paramName).toString();
			if(!StringUtil.isEmpty(value)){
				sql.appendSingle(template, handleParam.apply(value));
			}
		}
		return sql;
	}

	/**
	 * @param:         文件路径
	 * @Description:    是否是图片 true-是 false-否
	 * @Author:         mengmeng
	 * @Date:           2021/9/22 19:42
	 * @Version:        1.0
	 */
	private static boolean isImage(String path) {
		File file = new File(path);
		if (file!=null && file.exists() && file.isFile()) {
			try {
				BufferedImage bi = ImageIO.read(file);
				if (bi != null) {
					return true;
				}
			} catch (IOException e) {
				return false;
			}

		}
		return false;
	}
	/**
	  * 将pojo转换为map
	  * @author xinfushuo
	  * @param
	  * @throws
	  * @return
	  * @date 2023/3/17
	  * @modify
	  */
	@Override
	public Map<String,Object> convertToMap(Object object){
		ObjectMapper objectMapper  = new ObjectMapper();
		return objectMapper.convertValue(object,new TypeReference<Map<String,Object>>(){});
	}

	/**
	  * 获取一级部门编码
	  * @author xinfushuo
	  * @param 任意deptcode
	  * @throws
	  * @return
	  * @date 2023/3/21
	  * @modify
	  */
	public String getFristDeptCode(String deptcode){
		if(deptcode==null||deptcode.isEmpty()){
			return "";
		}
		deptcode=deptcode.trim();
		if(deptcode.contains("_")){
			if(deptcode.length()>deptcode.indexOf("_")+3){
				deptcode = deptcode.substring(0,deptcode.indexOf("_")+3);
			}
		}else{
			if(deptcode.length()>4){
				 deptcode = deptcode.substring(0,4);
			}
		}
		return deptcode;
	}

	/**
	 * @description: 生成消息任务对象
	 * @author: chengengwei
	 * @date: 2021-02-24
	 * @modify:
	 */
	@Override
	public BaseRemindTaskEntity createRemindTaskEntity(String sourceAction, String sourceid, String sourcetype, String subject, String content, Date remindtime, String usercode, String username) {
		BaseRemindTaskEntity remindTaskEntity = new BaseRemindTaskEntity();
		remindTaskEntity.setContent(content);
		remindTaskEntity.setCreateon(new Date());
		remindTaskEntity.setModifiedon(remindTaskEntity.getCreateon());
		remindTaskEntity.setNoticetype(BaseSystemConst.NoticeTypeEnum.App);
		remindTaskEntity.setSourcetype(sourcetype);
		remindTaskEntity.setSourceid(sourceid);
		remindTaskEntity.setSourceaction(sourceAction);
		remindTaskEntity.setFormtype(sourcetype);
		remindTaskEntity.setFormid(sourceid);
		remindTaskEntity.setRemindtime(remindtime);
		remindTaskEntity.setState(0);
		remindTaskEntity.setSubject(subject);
		remindTaskEntity.setUsercode(usercode);
		remindTaskEntity.setUsername(username);
		return remindTaskEntity;
	}
}
